import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Singleton class to store a collection of elves that need help from Santa
 * When 3 or more elves are present, they form and elf group and are sent
 * to ask Santa for help
 */
public class ElfQueue<E> extends ConcurrentLinkedQueue<E>{

	// auto generated serial id
	private static final long serialVersionUID = 1L;
	
	// Single reference to the ElfQueue
	private static ElfQueue<Elf> self;
	
	/**
	 * Private constructor of an elf queue
	 */
	private ElfQueue(){
		super();
	}
	
	/**
	 * Public accessor for the single ElfQueue reference
	 * Ensures that only a single ElfQueue is created
	 * @return Reference to the ElfQueue
	 */
	public static synchronized ElfQueue<Elf> getElfQueue(){
		if (self == null) self = new ElfQueue<Elf>();
		return self;
	}
	
	/**
	 * Adds an elf to the elf queue. If there are 3 or more elves
	 * in the queue, an elf group is created
	 * @param elf to be added
	 * @return true (as defined by collections.add)
	 */
	@Override
	public synchronized boolean add(E o){
		boolean result = super.add(o);
	
		if (getElfQueue().size() >= Properties.ELVES_PER_GROUP){
			makeElfGroup();
		}
		
		return result;
	}
	
	/**
	 * Creates an elf group from the first 3 elves in the queue.
	 * The group is then added to the winterHelperQueue and the
	 * elves go to ask Santa for help
	 */
	private void makeElfGroup(){
		
		Elf[] eGroup = new Elf[Properties.ELVES_PER_GROUP];
		
		for(int i = 0; i < Properties.ELVES_PER_GROUP; i++){
			eGroup[i] = getElfQueue().poll();
		}
		ElfGroup problemElves = new ElfGroup(eGroup);
		
		System.out.println(problemElves + " go to Santa's door.");
		
		WinterHelperQueue.getHelperQueue().add( problemElves );
	}
	
}
